Amazon SES で存在しない宛先にメール送信した際のバウンス通知の内容を確認してみた
コンバンハ、千葉(幸)です。
Amazon SES によるメール送信でバウンスが発生した場合、それを適切に把握することは大切です。
バウンスには以下の2タイプがあります。
- ハードバウンス
- メールアドレスが無効であるなどの理由で永続的にバウンスされるメール
- ソフトバウンス
- 受信ボックスがいっぱいである、一時的にメールサーバーが使用不可となっていた、など一時的な問題でバウンスされるメール
ここで、「存在しないメールアドレス」宛に Amazon SES からメール送信した際のバウンスの内訳を確認したい機会がありました。ここでの「存在しないメールアドレス」とは「ドメインが存在しない」「ドメインは存在するがユーザーが存在しない」の両方を含みます。
Amazon SES でバウンスが発生した場合その内容を Amazon SNS トピックに通知できるため、どんな通知内容になるかを確認してみました。
バウンス結果のまとめ
今回は以下の宛先にメール送信を行いました。
- ドメインが存在しないケース1:
dummy1@example.com
- ドメインが存在しないケース2:
dummy2@⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎
*1 - ドメインは存在するがユーザーが存在しないケース:
dummy3@▲▲▲.jp
*2- このメールアドレスのドメインではGmailを使用しています
それぞれの宛先に送信した際の結果は以下のとおりです。
送信先アドレス | bounceType | bounceSubType | status | 送信からバウンスまで |
---|---|---|---|---|
dummy1@example.com | Transient | General | 4.4.7 | 約950分 |
dummy2@⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎ | Transient | General | 4.4.7 | 約1,038分 |
dummy3@▲▲▲.jp | Permanent | General | 5.1.1 | 約7秒 |
なお、送信に使用した Amazon SES の条件は以下のとおりです。
- 東京リージョンの検証済み ID
- サンドボックスから移動済み
- コンソールの「テスト E メールの送信」より「カスタム」で宛先を指定
送信に使用したアイデンティティ
Amazon SES でメール送信する際には、アイデンティティ(ID)を作成・検証する必要があります。アイデンティティは E メールアドレスとして作成するか、ドメインとして作成するかが選択できます。
今回は E メールアドレスタイプのアイデンティティを作成しました。当該メールアドレスを、例示のため以降はsource@example.co.jp
と呼びます。
アイデンティティはほぼデフォルト状態です。
項目 | 設定 |
---|---|
DKIM | 該当なし |
カスタム MAIL FROM ドメイン | なし |
E メールのフィードバック転送 | 有効化 |
フィードバック通知 | Bounce のみ有効 |
承認ポリシー | なし |
デフォルト設定セット | なし |
アイデンティティの通知設定
通知の設定は、アイデンティティの詳細画面より以下のように確認できます。
「E メールのフィードバック転送」はデフォルトで有効になっており、バウンスや苦情のフィードバックが発生した際に E メールで通知を行います。今回の例で言えば、通知先はsource@example.co.jp
です。
参考:Receiving Amazon SES notifications through email - Amazon Simple Email Service
フィードバック通知は、フィードバックタイプごとに SNS トピックにメッセージを送信します。今回はフィードバックタイプBounce
を指定して、フィードバック通知を設定済みです。SNS トピックには E メールをサブスクライブしており、フィードバックイベントが発生すれば最終的にメール通知される構成になっています。
参考:Receiving Amazon SES notifications using Amazon SNS - Amazon Simple Email Service
Amazon SNS のフィードバック通知コンテンツ
Amazon SES のフィードバック通知により Amazon SNS に送信されるコンテンツの内訳は以下より確認できます。
特に、バウンスタイプについては以下のようにまとめられています。(ドキュメントの記述を一部省略して表現)
bounceType | bounceSubType | 説明 |
---|---|---|
Undetermined | Undetermined | Amazon SES がバウンスの理由を判断できるだけの十分な情報が含まれていない。 |
Permanent | General | 受取人の E メールプロバイダーがハードバウンスの原因を示していない。 |
Permanent | NoEmail | E メールアドレスが存在しない。 |
Permanent | Suppressed | 最近の履歴でハードバウンスを生じているため、Amazon SES サプレッションリストに追加されている。 |
Permanent | OnAccountSuppressionList | アカウントレベルのサプレッションリストにあるので、このアドレスへの送信を抑制した。 |
Transient | General | 受取人の E メールプロバイダーは一般的なバウンスメッセージを送信した。 |
Transient | MailboxFull | 受取人の受信トレイが満杯である。 |
Transient | MessageTooLarge | 受信したメッセージが大きすぎる。 |
Transient | ContentRejected | 受取人のプロバイダーが許可しないコンテンツが含まれていたた。 |
Transient | AttachmentRejected | 受取人プロバイダーが許容しない添付が含まれていた。 |
Permanent
がハードバウンス、Transient
がソフトバウンスを表します。
冒頭でまとめた結果の一部を引用すると、以下の結果です。
ケース | 送信先アドレス | bounceType | bounceSubType |
---|---|---|---|
ドメインが存在しない | dummy1@example.com | Transient | General |
ドメインが存在しない | dummy2@⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎ | Transient | General |
ユーザーが存在しない | dummy3@▲▲▲.jp | Permanent | General |
ドメインが存在しないケースではTransient
と評価されています。
また、ユーザーが存在しないケースの場合、バウンスサブタイプがGeneral
となっています。NoEmail
というサブタイプもあるのでそちらが記録されることも想像していたのですが、今回の検証結果では異なりました。
受信側のメールプロバイダーがどういったバウンスメッセージを返すかに依存する部分かと思います。
コンソールからのテスト E メールの送信
Amazon SES のコンソールから、テスト E メールを送信できます。(Amazon SES メールボックスシミュレーター)
画面の選択イメージは以下です。今回は以下のような指定でメール送信しました。
シナリオは複数から選択でき、選択したシナリオによって宛先が異なります。
シナリオ | Eメールアドレス |
---|---|
配信の成功 | success@simulator.amazonses.com |
バウンス | bounce@simulator.amazonses.com |
苦情 | complaint@simulator.amazonses.com |
サプレッションリスト上の受信者アドレス | suppressionlist@simulator.amazonses.com |
自動応答 | ooto@simulator.amazonses.com |
カスタム | 独自に指定 |
今回は「存在しないメールアドレス」に送信したいので、「カスタム」を選択しています。
参考:シミュレーターを使用した Amazon SES でのテストメール送信 - Amazon Simple Email Service
テストメールの送信の結果
テストメールの送信結果を見ていきます。
今回の例では、バウンスの結果として以下の通知が届きます。
- E メールのフィードバック転送によるメール通知(宛先は
source@example.co.jp
) - フィードバック通知による SNS 経由のメール通知(宛先は SNS トピックにサブスクライブされたもの)
両者の通知はほぼ同時に届きます。冒頭に記載したとおり、「ドメインが存在しない」ケースの場合、通知が届くまで15時間以上かかりました。
前者の「E メールのフィードバック転送」のイメージは以下です。
項目 | 値 |
---|---|
件名 | Delivery Status Notification (Failure) |
From | MAILER-DAEMON@ap-northeast-1.amazonses.com |
送信元 | e234-240.smtp-out.ap-northeast-1.amazonses.com |
後者のフィードバック通知のイメージは以下です。
項目 | 値 |
---|---|
件名 | AWS Notification Message |
From | no-reply@sns.amazonaws.com |
送信元 | us-west-2.amazonses.com |
後者のイベントの中身を、改行を加えた上でケースごとに確認していきます。
ケース1:存在しないドメインへの送信
{ "notificationType": "Bounce", "bounce": { "feedbackId": "0106018acf75f2fe-aa9dbf3a-6a37-4504-bbd4-9159d22fd4b2-000000", "bounceType": "Transient", "bounceSubType": "General", "bouncedRecipients": [ { "emailAddress": "dummy1@example.com", "action": "failed", "status": "4.4.7", "diagnosticCode": "smtp; 550 4.4.7 Message expired: unable to deliver in 840 minutes.<421 4.4.1 Unable to connect to remote host>" } ], "timestamp": "2023-09-26T03:08:48.000Z", "reportingMTA": "dns; e234-6.smtp-out.ap-northeast-1.amazonses.com" }, "mail": { "timestamp": "2023-09-25T11:18:18.762Z", "source": "source@example.co.jp", "sourceArn": "arn:aws:ses:ap-northeast-1:000000000000:identity/source@example.co.jp", "sourceIp": "xx.xx.xx.xx", "callerIdentity": "cm-chiba.yukihiro", "sendingAccountId": "000000000000", "messageId": "0106018acc0fbf8a-50deaec7-c22b-45b7-8f18-2d940db84ab1-000000", "destination": [ "dummy1@example.com" ] } }
diagnosticCodeとしていわゆるエラーメッセージが確認できます。
smtp; 550 4.4.7 Message expired: unable to deliver in 840 minutes.<421 4.4.1 Unable to connect to remote host>
840 分も待つんだな……という学びがあります。
ケース2:存在しないドメインへの送信
{ "notificationType": "Bounce", "bounce": { "feedbackId": "0106018acfc737ac-98d4145c-2925-49d7-9cb6-2a3125a0ccde-000000", "bounceType": "Transient", "bounceSubType": "General", "bouncedRecipients": [ { "emailAddress": "dummy2@⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎", "action": "failed", "status": "4.4.7", "diagnosticCode": "smtp; 550 4.4.7 Message expired: unable to deliver in 840 minutes.<421 4.4.0 Unable to lookup DNS for ⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎>" } ], "timestamp": "2023-09-26T04:37:34.000Z", "reportingMTA": "dns; e234-6.smtp-out.ap-northeast-1.amazonses.com" }, "mail": { "timestamp": "2023-09-25T11:19:50.537Z", "source": "source@example.co.jp", "sourceArn": "arn:aws:ses:ap-northeast-1:000000000000:identity/source@example.co.jp", "sourceIp": "xx.xx.xx.xx", "callerIdentity": "cm-chiba.yukihiro", "sendingAccountId": "000000000000", "messageId": "0106018acc112609-941219e0-ba5b-40ed-b301-865c1545e633-000000", "destination": [ "dummy2@⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎" ] } }
ケース1とほぼ同じ内容です。ただ、宛先がexample.com
の場合と異なりそもそも DNS ルックアップができていない、という細かい違いがあります。
smtp; 550 4.4.7 Message expired: unable to deliver in 840 minutes.<421 4.4.0 Unable to lookup DNS for ⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎>
ケース3:ユーザーが存在しない場合
{ "notificationType": "Bounce", "bounce": { "feedbackId": "0106018ad1486120-af114c55-0c0d-4e09-8635-cf49c1d4536f-000000", "bounceType": "Permanent", "bounceSubType": "General", "bouncedRecipients": [ { "emailAddress": "dummy3@▲▲▲.jp", "action": "failed", "status": "5.1.1", "diagnosticCode": "smtp; 550-5.1.1 The email account that you tried to reach does not exist. Please try\r\n 550-5.1.1 double-checking the recipient's email address for typos or\r\n 550-5.1.1 unnecessary spaces. Learn more at\r\n 550 5.1.1 https://support.google.com/mail/?p=NoSuchUser ba5-20020a0561220c8500b004962ad9a1d6si618529vkb.0 - gsmtp" } ], "timestamp": "2023-09-26T11:38:16.000Z", "reportingMTA": "dns; googlemail.com" }, "mail": { "timestamp": "2023-09-26T11:38:09.136Z", "source": "source@example.co.jp", "sourceArn": "arn:aws:ses:ap-northeast-1:000000000000:identity/source@example.co.jp", "sourceIp": "122.50.46.44", "callerIdentity": "cm-chiba.yukihiro", "sendingAccountId": "000000000000", "messageId": "0106018ad1484570-b35bc9b8-ae26-47d0-b9f1-d139308c57af-000000", "destination": [ "dummy3@▲▲▲.jp" ] } }
エラーメッセージには以下のように記録されています。受信側のEメールプロバイダがGmail を利用している環境なので、他の環境ではまた異なるメッセージが記録されるはずです。
smtp; 550-5.1.1 The email account that you tried to reach does not exist. Please try\r\n 550-5.1.1 double-checking the recipient's email address for typos or\r\n 550-5.1.1 unnecessary spaces. Learn more at\r\n 550 5.1.1 https://support.google.com/mail/?p=NoSuchUser ba5-20020a0561220c8500b004962ad9a1d6si618529vkb.0 - gsmtp
おまけ:バウンスのシミュレートの場合
今回の主旨とは外れますが、テストメールの送信の際にシナリオとしてbounce
を選択した場合のイベントも確認しておきます。(「E メールのフィードバック転送」も他のケースと同様に届いています。)
{ "notificationType": "Bounce", "bounce": { "feedbackId": "0106018acc0eca6c-8485ea19-6287-4d21-8b4b-4827f401342e-000000", "bounceType": "Permanent", "bounceSubType": "General", "bouncedRecipients": [ { "emailAddress": "bounce@simulator.amazonses.com", "action": "failed", "status": "5.1.1", "diagnosticCode": "smtp; 550 5.1.1 user unknown" } ], "timestamp": "2023-09-25T11:17:16.000Z", "remoteMtaIp": "xx.xx.xx.xx", "reportingMTA": "dns; e234-4.smtp-out.ap-northeast-1.amazonses.com" }, "mail": { "timestamp": "2023-09-25T11:17:14.991Z", "source": "source@example.co.jp", "sourceArn": "arn:aws:ses:ap-northeast-1:000000000000:identity/source@example.co.jp", "sourceIp": "xx.xx.xx.xx", "callerIdentity": "cm-chiba.yukihiro", "sendingAccountId": "000000000000", "messageId": "0106018acc0ec66f-4368cf8d-8f73-4fe7-8435-e969e24b5e12-000000", "destination": [ "bounce@simulator.amazonses.com" ] } }
終わりに
Amazon SES で「存在しない宛先」にメール送信した場合のバウンスの内容を確認してみました。
冒頭の表を再掲します。
送信先アドレス | bounceType | bounceSubType | status | 送信からバウンスまで |
---|---|---|---|---|
dummy1@example.com | Transient | General | 4.4.7 | 約950分 |
dummy2@⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎ | Transient | General | 4.4.7 | 約1,038分 |
dummy3@▲▲▲.jp | Permanent | General | 5.1.1 | 約7秒 |
ドメインが存在しない場合はバウンスタイプがTransient
(ソフトバウンス)であり、バウンス発生まで長時間かかることがわかりました。
また、ユーザーが存在しない場合でもバウンスサブタイプがGeneral
で返されることがあることがわかりました。
手を動かさないとわからない部分だったので、満足しました。
Amazon SES に限った話ではありませんが、バウンスの管理は重要です。
バウンス数が多い場合はつど通知しても埋もれてしまう危険性が高いため、今回紹介したようなメール通知のみでの検知の仕方はあまり有効でないと思います。Virtual Deliverability Manager dashboard などの仕組みをご活用ください。
数がそこまで多くない場合はお手軽に試せるメール通知も悪くないでしょう。SNS トピックでサブスクリプションを作成する際にはサブスクリプションフィルターポリシーによってフィルタリングすることもできますので、例えばバウンスタイプがPermanent
のものだけ通知する、というコントロールをすることである程度の量までは耐えうるかもしれません。
なんらか参考になれば幸いです。
以上、 チバユキ (@batchicchi) がお送りしました。
追記
実際にサブスクリプションフィルターでのフィルタリングを試してみました。
参考
- バウンスについて
- SMTP エラー メッセージについて - Google Workspace 管理者 ヘルプ
- Amazon SESのVirtual Deliverability Managerでバウンスメールの送信イベント履歴を確認してみた | DevelopersIO
- SESでバウンスした場合に送信元メールアドレスによってバウンス通知先を変える方法 | DevelopersIO